package com.zysd.collection.scheduler.service.channel;

import com.zysd.collection.scheduler.dao.ChannelDao;
import com.zysd.collection.scheduler.dao.ChannelStateDao;
import com.zysd.collection.scheduler.dao.OfflineScaleDao;
import com.zysd.collection.scheduler.entity.Channel;
import com.zysd.collection.scheduler.entity.ChannelState;
import com.zysd.collection.scheduler.entity.OfflineScale;
import com.zysd.collection.scheduler.entity.Terminal;
import com.zysd.collection.scheduler.service.record.RecordApiService;
import org.apache.commons.lang3.time.DateUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.text.NumberFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * Created by ht on 2017/3/9.
 */
@Service
public class OfflineScaleServiceImpl implements OfflineScaleService {


    private static NumberFormat nt = NumberFormat.getPercentInstance();
    static {
        nt.setMinimumFractionDigits(2);
    }
    private static final Logger LOGGER = LoggerFactory.getLogger(OfflineScaleServiceImpl.class);

    private static SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
    private static SimpleDateFormat dateFormat2 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

    @Autowired
    private OfflineScaleDao offlineScaleDao;
    @Autowired
    private RecordApiService recordApiService;

    @Autowired
    private ChannelDao channelDao;

    @Autowired
    private ChannelStateDao channelStateDao;


    @Override
    public int updateById(OfflineScale dto) {
        return offlineScaleDao.updateById(dto);
    }

    @Override
    public int insert(OfflineScale dto) {
        return offlineScaleDao.insert(dto);
    }

    @Override
    public OfflineScale byId(OfflineScale dto) {
        return offlineScaleDao.byId(dto);
    }

    @Override
    public Map findByMonth(Integer region, Integer local, String createDate) {
        return offlineScaleDao.findByMonth(region, local, createDate);
    }

    @Override
    public void saveOrUpdate(OfflineScale dto, boolean current) {
        OfflineScale persistent = byId(dto);
        if (persistent == null) {
            BigDecimal bigDecimal = new BigDecimal(dto.getOfflineTime());
            BigDecimal bigDecimal2 ;
            if(current){
                bigDecimal2 = new BigDecimal(dto.getOfflineTime());
            }else{
                bigDecimal2 = new BigDecimal(24*60);
            }
            dto.setOfflineScale(bigDecimal2.compareTo(new BigDecimal(0)) <= 0 ?  new BigDecimal(0) : bigDecimal.divide(bigDecimal2, 4, BigDecimal.ROUND_HALF_UP));
            insert(dto);
        } else {
            BigDecimal bigDecimal = new BigDecimal(dto.getOfflineTime());
            BigDecimal bigDecimal2 ;
            if(current){
                bigDecimal2 = new BigDecimal(dto.getOfflineTime());
            }else{
                bigDecimal2 = new BigDecimal(24*60);
            }
            dto.setOfflineScale(bigDecimal2.compareTo(new BigDecimal(0)) <= 0 ?  new BigDecimal(0) : bigDecimal.divide(bigDecimal2, 4, BigDecimal.ROUND_HALF_UP));
            updateById(dto);
        }
    }

    /**
     *  计算离线率
     * @param createDate
     * @throws ParseException
     */
    @Override
    public void scale(String createDate) throws ParseException {
        List<Terminal> list = recordApiService.getAllTerminals();
        for (Terminal terminal : list) {
            //查询当天时间所有的离线事件
            List<Channel> channelList = channelDao.findOffline(terminal.getRegionNo(), terminal.getLocalNo(), createDate);
            if (CollectionUtils.isEmpty(channelList)) {
                //当天无离线事件，存在两种情况：终端一致在线，终端下线
                //判断终端是否在线
                ChannelState channelState = channelStateDao.byId(new ChannelState(terminal.getRegionNo(), terminal.getLocalNo()));
                long min = getMin(createDate);
                if (channelState == null || channelState.getState() == 0) {
                    //终端未上线
                    saveOfflineScale(createDate ,terminal.getRegionNo(),terminal.getLocalNo() , min,0, new BigDecimal(1),true);
                } else if (channelState.getState() == 1) {
                    //终端在线
                    saveOfflineScale(createDate ,terminal.getRegionNo(),terminal.getLocalNo() , 0, 0, new BigDecimal(0),true);
                }
            }else{
                //存在离线事件
                //定义下线记录时长变量
                long minCache = 0;
                for(Channel channel : channelList){
                    //遍历离线事件获取上一条在线记录 计算离线时长
                    Channel preChannel = channelDao.findPre(channel.getId());
                    if(preChannel != null){
                        //计算离线时长
                        String onlineDate = preChannel.getCreateDate();
                        String offlineDate = channel.getCreateDate();
                        long min = getMin(offlineDate,onlineDate);
                        minCache = minCache + min;
                    }else{
                        //没有上线事件终端已下线
                        String offlineDate = channel.getCreateDate();
                        long min = getMin(dateFormat.format(dateFormat.parse(offlineDate) + " 23:59:59"), offlineDate);
                        minCache = minCache + min;
                    }
                    saveOfflineScale(createDate ,terminal.getRegionNo(),terminal.getLocalNo() , minCache, 0, new BigDecimal(0),false);
                }
            }
        }
    }


    /**
     * 获取当前createDate距离初始时间多少分钟
     * @param createDate
     * @return
     * @throws ParseException
     */
    private long getMin(String createDate) throws ParseException {
        Date date1 = dateFormat.parse(createDate);
        Date date2 = new Date();
        //验证日期是否是当天日期
        boolean sameDay = DateUtils.isSameDay(date1, date2);
        if (sameDay) {
            //当天日期需要计算分钟数
            //获取当天初始时间
            Date firstDate = dateFormat2.parse(createDate + " 00:00:00");
            return  (date2.getTime() - firstDate.getTime()) / 1000 / 60;
        } else {
            // 不是当天时间 默认就是
            return  24 * 60;
        }
    }

    private long getMin(String onlineDate ,String offlineDate) throws ParseException {
            Date online = dateFormat2.parse(onlineDate);
            Date offline = dateFormat2.parse(offlineDate);
            return  (online.getTime() - offline.getTime()) / 1000 / 60;
    }

    private void saveOfflineScale(String createDate , Integer region , Integer local , long offlineTime , long onlineTime , BigDecimal scale,boolean current){
        OfflineScale offlineScale = new OfflineScale();
        offlineScale.setCreateDate(createDate);
        offlineScale.setLocal(local);
        offlineScale.setRegion(region);
        offlineScale.setOfflineTime(offlineTime);
        offlineScale.setOnlineTime(onlineTime);
        offlineScale.setOfflineScale(scale);
        saveOrUpdate(offlineScale,current);
    }

}
